#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/wait.h>

void run_shell()
{
    char command[1024];
    char* args[64];
    
    while(1)
    {
        char cwd[1024];
        if(getcwd(cwd, sizeof(cwd)) != NULL)
        {
            printf("[%s] myshell> ", cwd);
        }
        else
        {
            perror("getcwd failed");
            printf("myshell> ");
        }

        if(fgets(command, sizeof(command), stdin) == NULL)
            continue;

        if(command[strlen(command) - 1] == '\n')
        {
            command[strlen(command) - 1] = '\0';
        }

        if(strcmp(command, "exit") == 0) break;
        
        //重定向输入和输出文本处理
        char output_file[128] = {0};
        char input_file[128] = {0};
        int append_mode = 0;

        char* input_redirect = strchr(command, '<');
        char* output_redirect = strstr(command, ">>");
        if(output_redirect)
        {
            append_mode = 1;
        }
        else
        {
            output_redirect = strchr(command, '>');
        }

        if(input_redirect)
        {
            *input_redirect = '\0';
            input_redirect++;
            while(*input_redirect == ' ') input_redirect++;
            sscanf(input_redirect, "%127s", input_file);
        }

        if(output_redirect)
        {
            *output_redirect = '\0';
            output_redirect += append_mode ? 2: 1;
            while(*output_redirect == ' ') output_redirect++;
            sscanf(output_redirect, "%127s", output_file);
        }

         // 分割命令为参数
        int i = 0;
        char* token = strtok(command, " ");
        while (token != NULL)
        {
            args[i++] = token;
            token = strtok(NULL, " ");
        }
        args[i] = NULL;

        // 添加 cd 命令处理（必须在主进程执行）
        if(args[0] != NULL && strcmp(args[0], "cd") == 0)
        {
            if(args[1] == NULL && strcmp(args[0], "cd") == 0)
            {
                fprintf(stderr, "cd: missing operand\n");
            }
            else
            {
                if (chdir(args[1]) != 0)
                {
                    perror("cd failed");
                }
            }
            continue; // 不再 fork
        }

        // fork 子进程执行其他命令
        pid_t pid = fork();
        if (pid == 0)
        {
            //重定向指令处理
            if (output_file[0] != '\0')
            {
                int flags = O_WRONLY | O_CREAT | (append_mode ? O_APPEND : O_TRUNC);
                int fd = open(output_file, flags, 0644);
                if (fd < 0)
                {
                    perror("open failed");
                    exit(1);
                }
                dup2(fd, STDOUT_FILENO);
                close(fd);
            }
            if(input_file[0] != '\0')
            {
                int fd = open(input_file, O_RDONLY);
                if(fd < 0)
                {
                    perror("open input failed");
                    exit(1);
                }
                dup2(fd, STDIN_FILENO);
                close(fd);
            }

            execvp(args[0], args);
            perror("exec failed");
            exit(1);
        }
        else if (pid > 0)
        {
            wait(NULL);
        }
        else
        {
            perror("fork failed");
        }
     }
}
